'''
Description: 
Author: notplus
Date: 2021-12-10 08:53:24
LastEditors: notplus
LastEditTime: 2021-12-14 18:59:00
FilePath: /cluster.py

Copyright (c) 2021 notplus
'''

from datetime import datetime
from math import pi
import pickle
import numpy as np
from numpy.core.fromnumeric import sort
from pyproj import Transformer
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN

import utils
from extra_stay_points import User, Trajectory, StayPoint, ActivityCluster
from dbscan import DBSCAN

# pickle_filename = 'activity.pickle'
pickle_filename = 'activity_128_date.pickle'

with open(pickle_filename, 'rb') as f:
    users = pickle.load(f)

all_activity = []
for user in users:
    all_activity += (user.trajs.stay_points)

all_activity.sort(key=lambda act: act.lev_t - act.arv_t)

time_interval = []

for user in users:
    i = 0
    point_num = len(user.trajs.stay_points)
    distance_matrix = np.zeros((point_num, point_num))
    time_interval_matrix = np.zeros((point_num, point_num))

    for i in range(len(user.trajs.stay_points)-1):
        # if (user.trajs.stay_points[i+1].arv_t - user.trajs.stay_points[i].lev_t).total_seconds() == 0:
        #     print('000')
        time_interval.append(
            (user.trajs.stay_points[i+1].arv_t - user.trajs.stay_points[i].lev_t).total_seconds())

    for i in range(point_num):
        for j in range(i + 1, point_num):
            distance_matrix[j][i] = distance_matrix[i][j] = utils.compute_dist(user.trajs.stay_points[i], user.trajs.stay_points[j])

    for i in range(point_num):
        for j in range(i + 1, point_num):
            arv_t = (user.trajs.stay_points[j].arv_t - user.trajs.stay_points[j].arv_t.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds() / 3600
            lev_t = (user.trajs.stay_points[i].arv_t - user.trajs.stay_points[i].arv_t.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds() / 3600
            
            time_interval_matrix[j][i] = time_interval_matrix[i][j] = abs(lev_t - arv_t)

    # np.save('time_interval_matrix28.npy', time_interval_matrix)
    # np.save('distance_matrix_153.npy', distance_matrix)

    # distance_matrix = np.load('distance_matrix_153.npy')
    # time_interval_matrix = np.load('time_interval_matrix_153.npy')

    print(np.mean(time_interval) / 3600)

    c = DBSCAN(user.trajs.stay_points, 0.63, 15, 1)

    all_activity_cluster = []
    for key in c:
        for act in c[key]:
            user.trajs.stay_points[act].id = key
    
    for key in c:
        activities = []
        next_activites = []

        for act in c[key]:
            activities.append(user.trajs.stay_points[act])
            if act < point_num - 1:
                next_activites.append(user.trajs.stay_points[act+1])
            else:
                next_activites.append(user.trajs.stay_points[act])
        all_activity_cluster.append(ActivityCluster(activities, next_activites))

    with open('all_activity_cluster_128.pickle', 'wb') as f:
        pickle.dump(all_activity_cluster, f)

    # with open('cluster_153.pickle', 'wb') as f:
    #     pickle.dump(c, f)
    
    # with open('cluster_153.pickle', 'rb') as f:
    #     c = pickle.load(f)

    # db = DBSCAN(eps=15, metric='precomputed', min_samples=1).fit(distance_matrix)
    # labels = db.labels_
    # n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)

    # # plt.figure()
    # # plt.hist(labels, bins=n_clusters_)

    # print('num cluster: %d' % (n_clusters_))
    label_sort = sorted(c, key=lambda key : len(c[key]))[::-1]
    
    # max_label = max(c, key=lambda key : len(c[key]))


    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    for j in range(5):
        x = []
        y = []
        z = []
        
        for i in c[label_sort[j]]:
            transformer = Transformer.from_crs("epsg:4326", "epsg:32650") 
            xt, yt = transformer.transform(user.trajs.stay_points[i].lat, user.trajs.stay_points[i].lng)
            x.append(xt)
            y.append(yt)
            z.append((user.trajs.stay_points[i].arv_t - user.trajs.stay_points[i].arv_t.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds() / 3600)
    
        ax.scatter(x, y, z, marker='^')

    for j in range(5):
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')

        x = []
        y = []
        z = []
        
        for i in c[label_sort[j]]:
            transformer = Transformer.from_crs("epsg:4326", "epsg:32650") 
            xt, yt = transformer.transform(user.trajs.stay_points[i].lat, user.trajs.stay_points[i].lng)
            x.append(xt)
            y.append(yt)
            z.append((user.trajs.stay_points[i].arv_t - user.trajs.stay_points[i].arv_t.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds() / 3600)
    
        ax.scatter(x, y, z, marker='^')


    print('')


